package top.iflyoung.cim.route.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import top.iflyoung.cim.common.facade.BaseChatFacade;
import top.iflyoung.cim.common.pojo.CIMUserInfo;
import top.iflyoung.cim.common.util.VerifyUtil;
import top.iflyoung.cim.route.service.UserInfoCacheService;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Function:
 *
 * @author crossoverJie
 * Date: 2018/12/24 11:06
 * @since JDK 1.8
 */
@Service
public class UserInfoCacheServiceImpl implements UserInfoCacheService {
    /**
     * todo 本地缓存，为了防止内存撑爆，后期可换为 LRU。
     */
    private final static Map<Long, CIMUserInfo> USER_INFO_MAP = new ConcurrentHashMap<>(64);

    @Autowired
    @Qualifier("sqlChatFacadeService")
    private BaseChatFacade baseChatFacadeService;

    @Override
    public CIMUserInfo loadUserInfoByUserId(Long userId) {
        //优先从本地缓存获取
        CIMUserInfo cimUserInfo = USER_INFO_MAP.get(userId);
        if (cimUserInfo != null) {
            return cimUserInfo;
        }
        //load redis
        CIMUserInfo redisUserInfo = baseChatFacadeService.getUserInfo(userId);
        if (!VerifyUtil.isEmpty(redisUserInfo.getUserName())) {
            USER_INFO_MAP.put(userId, redisUserInfo);
        }
        return redisUserInfo;
    }

    @Override
    public void removeLoginStatus(Long userId) throws Exception {
        throw new UnsupportedOperationException("现在统一到RedisChatFacadeService,暂不支持这个方法");
    }

    @Override
    public Set<CIMUserInfo> onlineUser() {
        Set<CIMUserInfo> set = null;
        Set<String> members = baseChatFacadeService.getOnlineUserIds();
        for (String member : members) {
            if (set == null) {
                set = new HashSet<>(64);
            }
            CIMUserInfo cimUserInfo = loadUserInfoByUserId(Long.parseLong(member));
            set.add(cimUserInfo);
        }
        return set;
    }

}
